import {UserDB,DataDB} from "@/datastore";
import path from "path";
import sha256 from "crypto-js/sha256";
import md5 from "crypto-js/md5";
import sha512 from "crypto-js/sha512";
import CryptoJS from "crypto-js";
import {aesEncrypt} from "@/utils/encrypt";
import fs from "fs-extra";

const DB={
    userDb:null,
    dataDb:null
}

//初始化适配器
export const initUerDB=()=>{
    DB.userDb=new UserDB();
}
export const initDataDB=(key,iv)=>{
    DB.dataDb=new DataDB(key,iv);
}

//将文件从存储的数据加载到vuex中
export const getUserData=()=>{
    const {password,iv}=DB.userDb.adapter.getState();
    return {
        password,iv
    }
}

//根据key和iv将加密内容解密
export const getHistoryData=()=>{
    const decrypt=DB.dataDb.decrypt;
    const content=decrypt(
        DB.dataDb.adapter.get('content').cloneDeep().value()
        );
    const history=decrypt(
        DB.dataDb.adapter.get('history').cloneDeep().value()
        );
    return{
        content,history
    }
}

//修改用户密码
export const modifyPassword = (password)=>{
    DB.userDb
        .adapter
        .set('password',password)
        .write();
}

//修改用户存储的部分内容数据
export const modifyContent=({id,name,value,createTime})=>{
    const encrypt = DB.dataDb.encrypt;
    DB.dataDb
        .adapter
        .get('content')
        .find({
            id:encrypt(id)
        }).assign({
            id:encrypt(id),
            name:encrypt(name),
            value:encrypt(value),
            createTime:encrypt(createTime)
        }).write();
}

//添加用户存储的部分内容数据
export const addContent=({id,name,value,createTime})=>{
    const encrypt = DB.dataDb.encrypt;
    DB.dataDb
        .adapter
        .get('content')
        .push({
            id:encrypt(id),
            name:encrypt(name),
            value:encrypt(value),
            createTime:encrypt(createTime)
        }).write();
}

//重新加密整个用户存储的内容数据
export const modifyWholeContent=(content)=>{
    const encrypt=DB.dataDb.encrypt;
    DB.dataDb
        .adapter
        .set('content',encrypt(JSON.parse(JSON.stringify(content))))
        .write();
}

export const saveContent=(content)=>{
    const encrypt=DB.dataDb.encrypt;
    DB.dataDb
        .adapter
        .set('content',encrypt(JSON.parse(JSON.stringify(content))))
        .write();
}

//添加操作历史记录
export const addHistory=(day,text)=>{
    const encrypt = DB.dataDb.encrypt;
    const name=`history.${day}`;
    if(DB.dataDb.adapter.has(name).value()){
        DB.dataDb
            .adapter
            .get(name)
            .push(encrypt(text))
            .write();
    }else{
        DB.dataDb
            .adapter
            .set(name,encrypt([text]))
            .write();
    }
}

//重新加密历史操作记录
export const modifyWholeHistory=(history)=>{
    const encrypt=DB.dataDb.encrypt;
    DB.dataDb
        .adapter
        .unset('history')
        .write();
    DB.dataDb
        .adapter
        .set('history',encrypt(JSON.parse(JSON.stringify(history))))
        .write();
}

export const deleteContentByI=(id)=>{
    const encrypt=DB.dataDb.encrypt;
    DB.dataDb
        .adapter
        .get('content')
        .remove({id:encrypt(id)})
        .write();
}

const thatPath=path;

export const exportData = async (path,password,content)=> {
    path = path.replaceAll('\\', '/');
    const key = md5(sha512(password).toString()).toString();
    const iv = CryptoJS.lib.WordArray.random(128 / 8).toString(CryptoJS.enc.Hex);
    const data = {
        password:sha256(password).toString(), iv, content: []
    }
    content.forEach(v => {
        data.content.push({
            name: aesEncrypt(v.name, {key, iv}),
            value: aesEncrypt(v.value, {key, iv})
        })
    })

    const write = async () => {
        return await new Promise((resolve, reject) => {
            fs.writeFile(thatPath.join(path, '/data.json'), JSON.stringify(data), (err) => {
                if (err) {
                    reject("数据导出失败");
                } else {
                    resolve('数据导出成功');
                }
            })
        });
    }
    return await new Promise((resolve, reject)=>{
        fs.pathExists(path).then(exists => {
            if (exists) {
                resolve(write());
            } else {
               reject('文件路径不存在')
            }
        }, () => reject('系统错误'))
    })
}

export const importData=async (path)=>{
    path=path.replaceAll('\\','/');
    const read=async ()=>{
        return new Promise((resolve, reject)=>{
            fs.readFile(path,(err,data)=>{
                if(err){
                    reject('文件读取失败');
                }else{
                    try {
                        resolve(JSON.parse(data.toString()));
                    }catch (e) {
                        reject('文件已损坏');
                    }
                }
            })
        })
    }
    return await new Promise((resolve, reject)=>{
        fs.pathExists(path).then(exists=>{
            if(exists)
                resolve(read());
            else
                reject('文件不存在')
        },()=>reject('系统错误'))
    })
}
